<template>
  <div class="props-table">
    <div
        v-for="(item, key) in finalProps"
        :key="key"
        class="prop-item"
    >
      <div class="label" v-if="item && item.text">
        {{item.text}}
      </div>
      <component
          v-if="item"
          :is="item.component"
          :value="item.value"
          v-bind="item.extraProps"
          v-on="item.events"
          class="content"
      >
        <template v-if="item.options">
          <component
              :is="item.subComponent"
              v-for="(option, index) in item.options"
              :key="index"
              :value="option.value"
          >
            <render-v-node :v-node="option.text"></render-v-node>
          </component>
        </template>
      </component>
    </div>
  </div>
</template>

<script lang="ts">
import {computed, defineComponent, PropType, VNode} from 'vue'
import {reduce} from "lodash-es";
import {mapPropsToForms} from "../propsMap.tsx";
import RenderVNode from "@/components/RenderVnode.ts";
import ColorPicker from "@/components/ColorPicker.vue";
import ImageProcessor from "@/components/ImageProcessor.vue";
import BackgroundProcessor from "@/components/BackgroundProcessor.vue";
import {AllProps} from "@/types/props.ts";

interface FormProps {
  component: string;
  subComponent?: string;
  value: any;
  extraProps?: { [key: string]: any };
  text?: string;
  options?: { text: string | VNode; value: any }[];
  valueProp: string;
  eventName: string;
  events: {[key: string]: (e: any) => void}
}

export default defineComponent({
  name: "PropsTable",
  props: {
    props: {
      type: Object as PropType<Partial<AllProps>>,
      required: true
    }
  },
  components: {
    ColorPicker,
    RenderVNode,
    ImageProcessor,
    BackgroundProcessor,
  },
  emits: ['change'],
  setup(props, ctx) {
    const finalProps = computed(() => {
      return reduce(props.props, (result, value: any, key: string) => {
        const newKey = key as keyof AllProps
        const item = mapPropsToForms[newKey]
        if (item) {
          const { valueProp = 'value', eventName = 'change', initTransform } = item
          result[newKey] = {
            ...item,
            value: initTransform ? initTransform(value) : value,
            valueProp,
            eventName,
            events: {
              [eventName]: (e: any) => {
                ctx.emit('change', {key, value: e})
              }
            }
          }
        }
        return result
      }, {} as {[key: string]: FormProps})
    })
    return {
      finalProps
    }
  }
})
</script>

<style scoped>
.prop-item {
  text-align: center;
  margin: 10px 0;
  display: flex;
  align-items: center;
  .label{
    width: 80px;
  }
  .content{
    width: calc(100% - 80px);
  }
}
</style>